﻿using HandyControl.Controls;
using IntoTheVoid.Units;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

public class CheatEngineDetector
{
	// 定义所需的 Windows API 函数
	[DllImport("kernel32.dll")]
	public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, uint dwProcessId);

	[DllImport("psapi.dll")]
	public static extern bool EnumProcessModules(IntPtr hProcess, IntPtr[] lphModule, uint cb, out uint lpcbNeeded);

	[DllImport("psapi.dll")]
	public static extern uint GetModuleFileNameEx(IntPtr hProcess, IntPtr hModule, StringBuilder lpBaseName, uint nSize);

	[DllImport("kernel32.dll")]
	public static extern bool CloseHandle(IntPtr hObject);

	// 设置进程访问权限
	const int PROCESS_QUERY_INFORMATION = 0x0400;
	const int PROCESS_VM_READ = 0x0010;

	private static readonly Lazy<CheatEngineDetector> _instance =
		new Lazy<CheatEngineDetector>(() => new CheatEngineDetector());

	private bool _isChecking = false;
	private Thread _checkCEThread;
	private Thread _checkModuleThread;

	private int _count = 0;
	private int _processId = 0;

	private bool _isShowMessage = false;

	private CheatEngineDetector() { }



	public static CheatEngineDetector Instance
	{
		get { return _instance.Value; }
	}

	public void Start(int id)
	{
		_processId = id;
		if (_checkCEThread == null || !_checkCEThread.IsAlive)
		{
			_isChecking = true;
			//// dll检测
			//_checkModuleThread = new Thread(CheckForDLLModule);
			//_checkModuleThread.Start();

			// ce检测
			_checkCEThread = new Thread(CheckForCheatEngine);
			_checkCEThread.Start();
		}

	}

	public void Stop()
	{
		if (_checkCEThread != null && _checkCEThread.IsAlive)
		{
			_isChecking = false;
			_checkCEThread.Join();

			// _checkModuleThread.Join();
			
		}
	}


	private void CheckForCheatEngine()
	{
		while (_isChecking)
		{
			// 限制上报100条
			if (_count >= 30)
			{
				_checkCEThread = null;
				return;
			}
			Thread.Sleep(60000);
			_count++;

			Process[] processes = Process.GetProcesses();
			bool cheatProgramFound = false;
			string name = "";
			foreach (var process in processes)
			{
				if (process.ProcessName.IndexOf("cheatengine", StringComparison.OrdinalIgnoreCase) >= 0 ||
				process.ProcessName.IndexOf("am819", StringComparison.OrdinalIgnoreCase) >= 0 ||
				process.ProcessName.IndexOf("按键精灵", StringComparison.OrdinalIgnoreCase) >= 0 ||
				process.ProcessName.IndexOf("OllyDbg", StringComparison.OrdinalIgnoreCase) >= 0 ||
				process.ProcessName.IndexOf("按键小精灵", StringComparison.OrdinalIgnoreCase) >= 0 
				//process.ProcessName.IndexOf("x64dbg", StringComparison.OrdinalIgnoreCase) >= 0 ||	// x64db
				//process.ProcessName.IndexOf("procexp", StringComparison.OrdinalIgnoreCase) >= 0
				)
				{
					cheatProgramFound = true;
					name = process.ProcessName;
					break;
				}
			}

			if (cheatProgramFound)
			{
				Common.ReportScreenshot("Cheat Program found", name);
				if(!_isShowMessage)
				{
					_isShowMessage = true;
					MessageBox.Show("已检测到电脑内存在调试工具或其他作弊工具，如果继续运行将面临封号危险，请退出相关作弊程序后继续运行游戏，如有疑问请加QQ群联系管理员","驱入虚空", System.Windows.MessageBoxButton.OK); 
					try
					{
						// 获取游戏进程并终止
						Process gameProcess = Process.GetProcessById(_processId);
						if (gameProcess != null && !gameProcess.HasExited)
						{
							gameProcess.Kill();
						}
					}
					catch (Exception ex)
					{
						LogHelper.Error(ex, "Stop Game Error");
					}
					
				}
			}
		}
	}
	//private HashSet<string> detectedModules = new HashSet<string>();
	//private bool isFirst = true;
	//private void CheckForDLLModule()
	//{
	//	uint processId = (uint)_processId;
	//	IntPtr hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, processId);

	//	if (hProcess == IntPtr.Zero)
	//		return;

	//	while (_isChecking)
	//	{
	//		if (_count >= 30)
	//		{
	//			_checkModuleThread = null;
	//			return;
	//		}

	//		if (isFirst)
	//			Thread.Sleep(30000);
	//		else
	//			Thread.Sleep(3* 60000);

	//		IntPtr[] hModules = new IntPtr[1024];
	//		uint bytesNeeded;
	//		if (EnumProcessModules(hProcess, hModules, (uint)(hModules.Length * IntPtr.Size), out bytesNeeded))
	//		{
	//			uint numModules = bytesNeeded / (uint)IntPtr.Size;
	//			StringBuilder sb = new StringBuilder(1024);
	//			for (uint i = 0; i < numModules; i++)
	//			{
	//				GetModuleFileNameEx(hProcess, hModules[i], sb, (uint)sb.Capacity);
	//				string modulePath = sb.ToString();

	//				if (isFirst)
	//				{
	//					detectedModules.Add(modulePath);
	//				}
	//				else
	//				{
	//					if (!detectedModules.Contains(modulePath))
	//					{
	//						// Common.ReportScreenshot("NewModule Report", modulePath);

	//						detectedModules.Add(modulePath);
	//					}
	//				}
	//				sb.Clear();
	//			}
	//			isFirst = false;
	//		}
	//	}
	//	CloseHandle(hProcess);
	//}
}
